﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FarseerPhysics.DemoBaseXNA.Components;
using FarseerPhysics.DemoBaseXNA;
using FarseerPhysics.DemoBaseXNA.ScreenSystem;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Dynamics.Joints;
using FarseerPhysics.Factories;
using FarseerPhysics.Collision;
using FarseerPhysics.Collision.Shapes;
using FarseerPhysics.Controllers;
using FarseerPhysics.Common;
using FarseerPhysics.Common.ConvexHull;
using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Common.PolygonManipulation;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

using ProjectMercury;
using ProjectMercury.Emitters;
using ProjectMercury.Modifiers;
using ProjectMercury.Renderers;

namespace SimpleSamplesXNA
{



    //renders particle to screen, needs to be static because of limited memory constraints
    static class particleEngine
    {
        public static List<ParticleFX> PFX = new List<ParticleFX>();

        //particle engine variables--------------------------
        public static ParticleFX particleEffects = new ParticleFX();
        public static Renderer particleRenderer;//renders particle effects to spritebatch
        public static ContentManager Content;


        //makes a new particleFX and adds to list, this is the default smoke one
        public static void createSmokeParticleFX()
        {
            PFX.Add(new ParticleFX());
        }


        //makes a new particleFX and adds to list, this is custom one
        public static void createParticleFX(int budget, float term)
        {

        }



        public static  void update(GameTime gameTime,KeyboardState newKS, KeyboardState oldKS)
        {


            //particle directions
            //set smoke to have new angle
            if (newKS.IsKeyDown(Keys.F1) && oldKS.IsKeyUp(Keys.F1))
            {
                particleEffects.setSmokeAngles(10, 0);
                particleEffects.particlEeffect[0].Initialise();
                particleEffects.particlEeffect[0].LoadContent(Content);
            }


        }




        public static void intitialize(GraphicsDeviceManager _graphics)
        {
            //Particles-------------------------------------------------------------------------------
            particleRenderer = new SpriteBatchRenderer
            {
                GraphicsDeviceService = _graphics,
            };
            //-----------------------------------------------------------------------------------------


            
        }



        public static void loadContent(ContentManager content)
        {
            particleEngine.Content = content;

            //particle load--------------
            foreach (ParticleFX pf in PFX)
            {
                pf.particlEeffect.Initialise();
                pf.particlEeffect.LoadContent(Content);
            }
            
            particleRenderer.LoadContent(Content);
        }




        public static void draw(GameTime gameTime, SpriteBatch sb)
        {
            //particle logic----------------------------
            foreach (ParticleFX pf in PFX)
            {
                pf.particlEeffect.Trigger(pf.Trigger);
                pf.particlEeffect.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
                particleRenderer.RenderEffect(pf.particlEeffect);
            }

            
            //------------------------------------------
        }
    }













    class ParticleFX
    {
        public ParticleEffect particlEeffect = new ParticleEffect();
        float gDirection = -1.57f;
        float gConeAngle = 0.6f;

        public Vector2 Trigger { get; set; }


        public ParticleFX()
        {

            init();
        }


        //defualt is grey smoke
        public void init()
        {
            particlEeffect = new ParticleEffect()
            {
                new ConeEmitter
                {
                    Budget = 200,
                    Term = 1f,
                    Name = "Smoke",
                    BlendMode = BlendMode.Alpha,
                    ReleaseQuantity = 1,
                    ReleaseRotation = new VariableFloat{Value = 0f, Variation = MathHelper.Pi},
                    ReleaseScale = new VariableFloat{Value = 16, Variation = 0},
                    ReleaseSpeed = new VariableFloat{Value = 250f, Variation = 100f},
                    ParticleTextureAssetName = "Textures\\Cloud001",
                    TriggerOffset = new Vector2(0,0),
                    MinimumTriggerPeriod = 0.05f,
                    ReleaseColour = new VariableFloat3{Value = new Vector3(0.5019608f, 0.5019608f, 0.5019608f), Variation = new Vector3(0,0,0)},
                    ReleaseImpulse = new Vector2(0,0),
                    ReleaseOpacity = new VariableFloat{Value = 1, Variation = 0},
                    Enabled = true,
                    Direction = gDirection,
                    ConeAngle = gConeAngle,
                    

                    Modifiers = new ModifierCollection
                    {
                        
                        new DampingModifier
                        {
                            DampingCoefficient = 0.95f,
                        },

                        new ScaleModifier
                        {
                            InitialScale = 64f,
                            UltimateScale = 256f,
                        },

                        new RotationRateModifier
                        {
                            InitialRate = 1.57079637f,
                            FinalRate = 0,
                        },

                        new LinearGravityModifier
                        {
                            Gravity = new Vector2(150,0),
                        },

                        new OpacityInterpolatorModifier
                        {
                            InitialOpacity = 0,
                            MiddleOpacity = 0.5f,
                            MiddlePosition = 0.1f,
                            FinalOpacity = 0,
                        },

                        

                    },

                }};
        }

        public void setSmokeAngles(float dir, float ang)
        {
            gConeAngle = ang;
            gDirection = dir;
            init();
        }








    }
}
